package com.open.server;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.open.bean.IpWhite;
import com.open.bean.RequestToken;
import com.open.bean.vo.OpenVo;
import com.open.service.IpWhiteService;
import com.open.service.RequestTokenService;
import com.open.util.ImgUtil;
import com.open.util.RandomUtil;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * @author tanyongpeng
 * <p>ai绘画调用服务</p>
 **/
@Component
public class ImgAIServer {

    @Autowired
    RequestTokenService requestTokenService;

    public OpenVo getImg(JSONObject params, String wid, IpWhiteService ipWhiteService){
        OpenVo openVo = new OpenVo();
        try {
            openVo.setMsg("成功");
            openVo.setState(true);
            List<RequestToken> requestTokenList = requestTokenService.lambdaQuery()
                    .eq(RequestToken::getTokenType, 1)
                    .eq(RequestToken::getSignStatus,0)
                    .gt(RequestToken::getBalance, 0).list();
            if (requestTokenList.size() == 0){
                openVo.setState(false);
                openVo.setMsg("今日绘画服务器已经关闭，请明日再试");
                return openVo;
            }
            RequestToken requestToken = requestTokenList.get(RandomUtil.getRandom().nextInt(requestTokenList.size()));
            String tokenBody = HttpRequest.get("https://flagopen.baai.ac.cn/flagStudio/auth/getToken?apikey=" + requestToken.getSign())
                    .header("Accept", "application/json")
                    .execute().charset("utf-8")
                    .body();
            JSONObject jsonObject = JSONUtil.parseObj(tokenBody);
            String token = jsonObject.getJSONObject("data").getStr("token");
            String body = HttpRequest.post("https://flagopen.baai.ac.cn/flagStudio/v1/text2img")
                    .header("Content-Type", "application/json")
                    .header("Accept", "application/json")
                    .header("token", token)
                    .body(params.toString())
                    .charset("utf-8").execute().body();
            JSONObject parseObj = JSONUtil.parseObj(body);
            if (parseObj.getInt("code") == 200){
                String imgBase64 = parseObj.getStr("data");
                String image = ImgUtil.generateImage(imgBase64,ImgUtil.AI_IMG_PATH,".jpg");
                if (StrUtil.isBlank(image)){
                    openVo.setState(false);
                    openVo.setMsg("图片上传失败，请重试");
                }
                requestTokenService.lambdaUpdate()
                        .set(RequestToken::getBalance,requestToken.getBalance()-1)
                        .eq(RequestToken::getTid,requestToken.getTid()).update();
                IpWhite ipWhite = ipWhiteService.getById(wid);
                ipWhiteService.lambdaUpdate()
                        .set(IpWhite::getRequestCount,ipWhite.getRequestCount() - 3)
                        .eq(IpWhite::getWid,wid).update();
                openVo.setData(image);
            }else {
                openVo.setState(false);
                openVo.setMsg(parseObj.getStr("nsfw").equals("0")?"绘画失败，请稍后再试":"你的图片违规，图片违规多次后，你的账户将封禁");
            }
            return openVo;
        }catch (Exception e){
            e.printStackTrace();
            openVo.setState(false);
            openVo.setMsg("程序内部异常");
            return openVo;
        }
    }

}
